#!/usr/bin/env python3
"""
智能宠物小屋远程控制服务器
提供REST API和WebSocket接口供手机APP使用
"""
import asyncio
import json
import random
import time
from datetime import datetime
from typing import Dict, List
import logging

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI()

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 全局状态存储
class PetHouseState:
    def __init__(self):
        self.temperature = 24.5
        self.humidity = 65
        self.food_weight = 350
        self.water_level = 85
        self.fan_status = False
        self.pump_status = False
        self.servo_position = 0
        self.wifi_connected = True
        self.stm32_status = "normal"
        self.last_update = datetime.now()
        
    def to_dict(self) -> Dict:
        return {
            "temperature": self.temperature,
            "humidity": self.humidity,
            "food_weight": self.food_weight,
            "water_level": self.water_level,
            "fan_status": self.fan_status,
            "pump_status": self.pump_status,
            "servo_position": self.servo_position,
            "wifi_connected": self.wifi_connected,
            "stm32_status": self.stm32_status,
            "last_update": self.last_update.isoformat()
        }

# 初始化状态
pet_house = PetHouseState()

# WebSocket连接管理
class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)
        logger.info(f"WebSocket连接已建立，当前连接数: {len(self.active_connections)}")

    def disconnect(self, websocket: WebSocket):
        if websocket in self.active_connections:
            self.active_connections.remove(websocket)
        logger.info(f"WebSocket连接已断开，当前连接数: {len(self.active_connections)}")

    async def send_personal_message(self, message: str, websocket: WebSocket):
        try:
            await websocket.send_text(m)
        except:
            pass

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            try:
                await connection.send_text(message)
            except:
                pass

manager = ConnectionManager()

# 数据模型
class ControlCommand(BaseModel):
    action: str
    value: bool = None
    amount: int = None

class Settings(BaseModel):
    temp_threshold: float = 30.0
    food_threshold: int = 100
    water_threshold: int = 200

# 模拟STM32通信
class STM32Simulator:
    def __init__(self):
        self.running = True
        
    async def simulate_data_update(self):
        """模拟STM32数据更新"""
        while self.running:
            # 模拟传感器数据变化
            pet_house.temperature = round(20 + random.random() * 10, 1)
            pet_house.humidity = int(50 + random.random() * 30)
            pet_house.food_weight = max(0, pet_house.food_weight - random.randint(0, 5))
            pet_house.water_level = max(0, pet_house.water_level - random.randint(0, 2))
            pet_house.last_update = datetime.now()
            
            # 自动温控逻辑
            if pet_house.temperature > 28.0:
                pet_house.fan_status = True
            else:
                pet_house.fan_status = False
                
            # 自动补水逻辑
            if pet_house.water_level < 30:
                pet_house.pump_status = True
            elif pet_house.water_level > 80:
                pet_house.pump_status = False
            
            # 广播更新
            await manager.broadcast(json.dumps({
                "type": "data_update",
                "data": pet_house.to_dict()
            }))
            
            await asyncio.sleep(5)  # 每5秒更新一次

    def stop(self):
        self.running = False

simulator = STM32Simulator()

# API路由
@app.get("/")
async def root():
    """根路由"""
    return {"message": "智能宠物小屋远程控制服务器", "version": "1.0.0"}

@app.get("/api/status")
async def get_status():
    """获取当前状态"""
    return pet_house.to_dict()

@app.post("/api/control")
async def control_device(command: ControlCommand):
    """控制设备"""
    try:
        if command.action == "feed":
            # 模拟投食
            pet_house.servo_position = 180
            pet_house.food_weight = min(500, pet_house.food_weight + 50)
            logger.info("执行投食操作")
            
            # 延迟后复位舵机
            await asyncio.sleep(2)
            pet_house.servo_position = 0
            
        elif command.action == "toggle_fan":
            pet_house.fan_status = command.value
            logger.info(f"风扇状态: {'开启' if command.value else '关闭'}")
            
        elif command.action == "toggle_pump":
            pet_house.pump_status = command.value
            logger.info(f"水泵状态: {'开启' if command.value else '关闭'}")
            
        # 广播状态更新
        await manager.broadcast(json.dumps({
            "type": "control_response",
            "action": command.action,
            "success": True,
            "data": pet_house.to_dict()
        }))
        
        return {"success": True, "message": "操作成功", "data": pet_house.to_dict()}
        
    except Exception as e:
        logger.error(f"控制操作失败: {e}")
        return {"success": False, "message": str(e)}

@app.get("/api/history")
async def get_history(hours: int = 24):
    """获取历史数据"""
    # 模拟历史数据
    history = []
    base_time = datetime.now()
    
    for i in range(hours * 12):  # 每5分钟一个数据点
        history.append({
            "timestamp": (base_time - timedelta(minutes=i*5)).isoformat(),
            "temperature": round(20 + random.random() * 10, 1),
            "humidity": int(50 + random.random() * 30),
            "food_weight": 400 - i * 2,
            "water_level": 90 - i
        })
    
    return {"data": history[::-1]}

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """WebSocket端点"""
    await manager.connect(websocket)
    try:
        # 发送初始状态
        await websocket.send_text(json.dumps({
            "type": "initial_data",
            "data": pet_house.to_dict()
        }))
        
        while True:
            # 保持连接
            data = await websocket.receive_text()
            message = json.loads(data)
            
            if message.get("type") == "ping":
                await websocket.send_text(json.dumps({"type": "pong"}))
                
    except WebSocketDisconnect:
        manager.disconnect(websocket)

# 启动函数
if __name__ == "__main__":
    import uvicorn
    
    # 启动服务器
    uvicorn.run(
        "server:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
        log_level="info"
    )